home *** CD-ROM | disk | FTP | other *** search
/ Amiga Plus Leser 19 / Amiga Plus Leser CD 19.iso / Tools / MorphOS / cvs-1.11.2 / contrib / cvs_acls < prev    next >
Encoding:
Text File  |  2002-11-18  |  6.5 KB  |  185 lines

  1. #! /usr/bin/perl
  2. # -*-Perl-*-
  3. #
  4. # Access control lists for CVS.  dgg@ksr.com (David G. Grubbs)
  5. # Branch specific controls added by voisine@bytemobile.com (Aaron Voisine)
  6. #
  7. # CVS "commitinfo" for matching repository names, running the program it finds
  8. # on the same line.  More information is available in the CVS man pages.
  9. #
  10. # ==== INSTALLATION:
  11. #
  12. # To use this program as I intended, do the following four things:
  13. #
  14. # 0. Install PERL.  :-)
  15. #
  16. # 1. Put one line, as the *only* non-comment line, in your commitinfo file:
  17. #
  18. #    DEFAULT        /usr/local/bin/cvs_acls
  19. #
  20. # 2. Install this file as /usr/local/bin/cvs_acls and make it executable.
  21. #
  22. # 3. Create a file named $CVSROOT/CVSROOT/avail.
  23. #
  24. # ==== FORMAT OF THE avail FILE:
  25. #
  26. # The avail file determines whether you may commit files.  It contains lines
  27. # read from top to bottom, keeping track of a single "bit".  The "bit"
  28. # defaults to "on".  It can be turned "off" by "unavail" lines and "on" by
  29. # "avail" lines.  ==> Last one counts.
  30. #
  31. # Any line not beginning with "avail" or "unavail" is ignored.
  32. #
  33. # Lines beginning with "avail" or "unavail" are assumed to be '|'-separated
  34. # triples: (All spaces and tabs are ignored in a line.)
  35. #
  36. # {avail.*,unavail.*} [|user,user,... [|repos,repos,... [|branch,branch,...]]]
  37. #
  38. #    1. String starting with "avail" or "unavail".
  39. #    2. Optional, comma-separated list of usernames.
  40. #    3. Optional, comma-separated list of repository pathnames.
  41. #    These are pathnames relative to $CVSROOT.  They can be directories or
  42. #    filenames.  A directory name allows access to all files and
  43. #    directories below it.
  44. #    4. Optional, comma-separated list of branch tags.
  45. #    If not specified, all branches are assumed. Use HEAD to reference the
  46. #    main branch.
  47. #
  48. # Example:  (Text from the ';;' rightward may not appear in the file.)
  49. #
  50. #    unavail            ;; Make whole repository unavailable.
  51. #    avail|dgg        ;; Except for user "dgg".
  52. #    avail|fred, john|bin/ls    ;; Except when "fred" or "john" commit to
  53. #                ;; the module whose repository is "bin/ls"
  54. #    avail|ed|/bin/ls|stable ;; Except when "ed" commits to the "stable"
  55. #                ;; branch of the "bin/ls" repository 
  56. #
  57. # PROGRAM LOGIC:
  58. #
  59. #    CVS passes to @ARGV an absolute directory pathname (the repository
  60. #    appended to your $CVSROOT variable), followed by a list of filenames
  61. #    within that directory.
  62. #
  63. #    We walk through the avail file looking for a line that matches the
  64. #    username, repository and branch.
  65. #
  66. #    A username match is simply the user's name appearing in the second
  67. #    column of the avail line in a space-or-comma separate list.
  68. #
  69. #    A repository match is either:
  70. #        - One element of the third column matches $ARGV[0], or some
  71. #          parent directory of $ARGV[0].
  72. #        - Otherwise *all* file arguments ($ARGV[1..$#ARGV]) must be
  73. #          in the file list in one avail line.
  74. #        - In other words, using directory names in the third column of
  75. #          the avail file allows committing of any file (or group of
  76. #          files in a single commit) in the tree below that directory.
  77. #        - If individual file names are used in the third column of
  78. #          the avail file, then files must be committed individually or
  79. #          all files specified in a single commit must all appear in
  80. #          third column of a single avail line.
  81. #
  82. #    A branch match is either:
  83. #        - When no branches are listed in the fourth column.
  84. #        - One element from the fourth column matches each of the tag
  85. #          names for $ARGV[1..$#ARGV] found in the CVS/Entries file.
  86. #        - HEAD specified in the fourth column will match if there
  87. #          is no tag listed in the CVS/Entries file.
  88. #
  89.  
  90. $debug = 0;
  91. $cvsroot = $ENV{'CVSROOT'};
  92. $availfile = $cvsroot . "/CVSROOT/avail";
  93. $entries = "CVS/Entries";
  94. $myname = $ENV{"USER"} if !($myname = $ENV{"LOGNAME"});
  95.  
  96. eval "print STDERR \$die='Unknown parameter $1\n' if !defined \$$1; \$$1=\$';"
  97.     while ($ARGV[0] =~ /^(\w+)=/ && shift(@ARGV));
  98. exit 255 if $die;        # process any variable=value switches
  99.  
  100. die "Must set CVSROOT\n" if !$cvsroot;
  101. ($repos = shift) =~ s:^$cvsroot/::;
  102. grep($_ = $repos . '/' . $_, @ARGV);
  103.  
  104. print "$$ Repos: $repos\n","$$ ==== ",join("\n$$ ==== ",@ARGV),"\n" if $debug;
  105.  
  106. $exit_val = 0;                # Good Exit value
  107.  
  108. $universal_off = 0;
  109.  
  110. my %branch;
  111. my $f;
  112.  
  113. open(ENTRIES, $entries) || die("Cannot open $entries.\n");
  114. while(<ENTRIES>) {
  115.     chop;
  116.     next if /^\s*$/;
  117.     if(m|^[^/]*/([^/]*)/(?:[^/]*/)*[^/]?([^/]*)$|) {
  118.     $branch{$repos . '/' . $1} = ($2) ? $2 : "HEAD"; 
  119.     print "$$ $1/$2\n" if $debug;
  120.     }
  121. }
  122. close(ENTRIES);
  123.  
  124. open (AVAIL, $availfile) || exit(0);    # It is ok for avail file not to exist
  125. while (<AVAIL>) {
  126.     chop;
  127.     next if /^\s*\#/;
  128.     next if /^\s*$/;
  129.     ($flagstr, $u, $m, $b) = split(/[\s,]*\|[\s,]*/, $_);
  130.  
  131.     # Skip anything not starting with "avail" or "unavail" and complain.
  132.     (print "Bad avail line: $_\n"), next
  133.     if ($flagstr !~ /^avail/ && $flagstr !~ /^unavail/);
  134.  
  135.     # Set which bit we are playing with. ('0' is OK == Available).
  136.     $flag = (($& eq "avail") ? 0 : 1);
  137.  
  138.     # If we find a "universal off" flag (i.e. a simple "unavail") remember it
  139.     $universal_off = 1 if ($flag && !$u && !$m && !$b);
  140.  
  141.     # $myname considered "in user list" if actually in list or is NULL
  142.     $in_user = (!$u || grep ($_ eq $myname, split(/[\s,]+/,$u)));
  143.     print "$$ \$myname($myname) in user list: $_\n" if $debug && $in_user;
  144.  
  145.     # Module matches if it is a NULL module list in the avail line.  If module
  146.     # list is not null, we check every argument combination.
  147.     if (!($in_repo = !$m)) {
  148.     @tmp = split(/[\s,]+/,$m);
  149.     for $j (@tmp) {
  150.         # If the repos from avail is a parent(or equal) dir of $repos, OK
  151.         $in_repo = 1, last if ($repos eq $j || $repos =~ /^$j\//);
  152.     }
  153.     if (!$in_repo) {
  154.         $in_repo = 1;
  155.         for $j (@ARGV) {
  156.         last if !($in_repo = grep ($_ eq $j, @tmp));
  157.         }
  158.     }
  159.     }
  160.     print "$$ \$repos($repos) in repository list: $_\n" if $debug && $in_repo;
  161.  
  162.     # Branch matches if it is in the branch list in the avail line, the branch
  163.     # list is NULL, or there is no branch and HEAD is in the branch list.
  164.     if(!($in_branch = !$b)) {
  165.     @bls = split (/[\s,]+/,$b);
  166.  
  167.     for $j (@ARGV) {
  168.        $f = $j;
  169.        last if !($in_branch = grep($_ eq $branch{$j}, @bls)); 
  170.     }
  171.     }
  172.     print "$$ \$branch($branch{$f}) in branch list: $_\n"
  173.     if $debug && $in_branch;
  174.  
  175.     $exit_val = $flag if ($in_user && $in_repo && $in_branch);
  176.     print "$$ ==== \$exit_val = $exit_val\n$$ ==== \$flag = $flag\n" if $debug;
  177. }
  178. close(AVAIL);
  179. print "$$ ==== \$exit_val = $exit_val\n" if $debug;
  180. print "**** Access denied: Insufficient Karma ($myname|$repos|$branch{$f})\n"
  181.     if $exit_val;
  182. print "**** Access allowed: Personal Karma exceeds Environmental Karma.\n"
  183.     if $universal_off && !$exit_val;
  184. exit($exit_val);
  185.